#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <vector>
#define BLOCK_SIGNAL 2 // 要屏蔽的信号
#define MAX_SIGNUM 41  // 信号个数

using namespace std;

static void show_pending(const sigset_t &pending)
{

    for (int signo = MAX_SIGNUM; signo >= 1; signo--)
    {
        if (sigismember(&pending, signo))
        {
            cout << "1";
        }
        else
            cout << "0";
    }
    cout << "\n";
}

static void myhandler(int signo)
{
    cout << signo << " 号信号已经被递达!!" << endl;
}

// 屏蔽多个信号
vector<int> sigarr = {2, 40};
int main()
{
    // for (auto sig : sigarr)
    //     signal(sig, myhandler);

    // // 1.屏蔽指定的信号
    // // oblock输出
    // sigset_t block, oblock, pending;
    // // 1.1初始化
    // sigemptyset(&block);
    // sigemptyset(&oblock);
    // sigemptyset(&pending);
    // // 1.2添加要屏蔽的关键字
    // // sigaddset(&block,BLOCK_SIGNAL);
    // // 屏蔽多个
    // for (auto sig : sigarr)
    //     sigaddset(&block, sig);

    // //1.3开始屏蔽,设计进内核（进程）单次屏蔽

    // sigprocmask(SIG_BLOCK,&block,&oblock);

    // //2.遍历打印pending信号集
    // int cnt=10;
    // while (true)
    // {
    //     //2.1 初始化
    //     sigemptyset(&pending);
    //     //2.2  获取pending信号集
    //     sigpending(&pending);
    //     //2.3  打印信号集
    //     show_pending(pending);

    //     sleep(1);
    //     if(cnt--==0)
    //     {
    //         //放在恢复前面才能打印出来，对特定信号解除屏蔽
    //         //OS要立马递达一个信号，默认终止进程，不会返回用户态执行
    //         //cout<<"恢复对信号的屏蔽，不再屏蔽\n";
    //         sigprocmask(SIG_SETMASK,&oblock,&block);
    //         //设置捕捉的自定义行为才能把它放在重设BLOCK后面
    //         cout<<"恢复对信号的屏蔽，不再屏蔽\n";
    //     }
    // }

    //循环屏蔽
    sigset_t block, oblock, pending;
    // 1.1初始化
    sigemptyset(&block);
    sigemptyset(&oblock);
    sigemptyset(&pending);
    for (auto sig : sigarr) sigaddset(&block, sig);
    for (auto sig : sigarr) signal(sig, myhandler);

    while (1)
    {
        sigprocmask(SIG_BLOCK,&block,&oblock);

        int cnt=10;
        while (true)
        {
            //2.1 初始化
            sigemptyset(&pending);
            //2.2  获取pending信号集
            sigpending(&pending);
            //2.3  打印信号集
            show_pending(pending);

            sleep(1);
            if(cnt--==0)
            {
                
                sigprocmask(SIG_SETMASK,&oblock,&block);
                
                cout<<"恢复对信号的屏蔽，不再屏蔽\n";
                break;
            }
        }
    }


}

// #include <stdio.h>
// #include <signal.h>

// #include <unistd.h>
// void handler(int sig)
// {
//     printf("get a sig:%d\n", sig);
// }
// void showpending(sigset_t *pending)
// {
//     int i = 0;
//     for (; i <= 31; i++)
//     {
//         if (sigismember(pending, i))
//             printf("1");
//         else
//             printf("0");
//     }
//     printf("\n");
// }
// int main()
// {
//     sigset_t blockSet, oblockSet, pending;
//     sigemptyset(&blockSet);
//     sigemptyset(&oblockSet);
//     sigaddset(&blockSet, 2);

//     while (1) // 添加while循环，使信号可以被屏蔽多次
//     {
//         signal(2, handler);
//         sigprocmask(SIG_SETMASK, &blockSet, &oblockSet);
//         int count = 1;
//         while (1)
//         {
//             sigpending(&pending);
//             showpending(&pending);
//             sleep(1);
//             if (count++ == 10)
//             {
//                 printf("recover proc block set\n");
//                 sigprocmask(SIG_SETMASK, &oblockSet, NULL);
//                 break; // 跳出循环
//             }
//         }
//     }
// }
